# 开发指南篇 4:数据驱动与拼图游戏
数据驱动是 Vue 框架的核心特性之一,也是 Vue 响应式原理的具体体现,相信大家对其应该深有体会,尤其是在操作数据来触发页面更新的时候。
为了让大家更加了解数据驱动的理念,并解决使用过程中可能出现的一系列问题,本文将结合比较常见和简单的 “拼图游戏” 来展示 Vue 数据驱动的魅力所在。
# 效果展示
首先我们先来看一下实现的 “拼图游戏” 的动态效果:

在不操作 DOM 的情况下实现以上功能其实需要我们对 Vue 数据驱动及数据可视化有一个非常清楚的认知,在操作数据的同时驱动可视化界面的还原。
# 关键代码
接下来我们来看一下实现该拼图游戏的功能点及关键代码:
# 游戏面板的构建
<!-- HTML 部分 -->
<ul class="puzzle-wrap">
<li
:class="{'puzzle': true, 'puzzle-empty': !puzzle}"
v-for="(puzzle, index) in puzzles"
:key="index"
v-text="puzzle"
></li>
</ul>
@前端进阶之旅: 代码已经复制到剪贴板
// 数据部分
export default {
data() {
return {
puzzles: Array.from({ length: 15 }, (value, index) => index + 1)
}
},
}
@前端进阶之旅: 代码已经复制到剪贴板
上方我们使用 v-for 循环构建了从 1 ~ 15 按顺序排列的方块格子,也就是拼图完成时候的顺序,但是拼图游戏一开始数字的顺序应该是无序的,也是随机打乱的,那么我们怎么实现呢?可以使用下方的随机排列函数:
function shuffle(arr) {
let len = arr.length
for (let i = 0; i < len - 1; i++) {
let idx = Math.floor(Math.random() * (len - i))
let temp = arr[idx]
arr[idx] = arr[len - i - 1]
arr[len - i - 1] = temp
}
return arr
}
@前端进阶之旅: 代码已经复制到剪贴板
该函数中我们使用 Math.random() 来返回 0 和 1 之间的伪随机数,可能为 0,但总是小于1,[0, 1),而通过这一特性我们可以实现生成 n-m,包含 n 但不包含 m 的整数,具体步骤如下:
- 第一步算出
m-n的值,假设等于 w - 第二步
Math.random() * w - 第三步
Math.random() * w + n - 第四步
Math.floor(Math.random() * w + n)
在 shuffle 函数中 n 值永远是 0,而 w(即 len - i) 值随着循环 i 值的变大而不断减小。
在上面的算法里,我们每一次循环从前 len - i 个元素里随机一个位置,将这个元素和第 len - i 个元素进行交换,迭代直到 i = len - 1 为止。
这一便实现了数组的随机打乱。最后我们需要在数组末尾追加一个空值来显示唯一一个空白格子:
this.puzzles.push('');
@前端进阶之旅: 代码已经复制到剪贴板
# 交换方块位置
实现随机数字后,当我们点击方块,如果其上下左右存在为空的格子就需要将其进行交换,而由于是数据驱动界面,这里我们便需要交换两者在数组中的位置来实现:
export default {
methods: {
// 点击方块
moveFn(in